#include <iostream>
#include <cstring>

#define NAMESIZE	32

using namespace std;

class Person {
	// private:
	protected:
		// 成员变量
		int m_id;
		char m_name[NAMESIZE];
		// char *tel;
	private:
		// 静态成员变量
		static int cnt;
	public:
		// 成员方法
		Person();
		Person(int id, const char *name); // constructor
		Person(const Person &p);
		~Person();
		void show();
		void setId(int id);
		void setName(const char *name);
	
		// 常函数
		int getId() const;

		// 静态成员函数
		static int getCnt();
		// 友元函数
		friend void showPerson(const Person &s);
};

// 初始化静态成员
int Person::cnt = 0;

Person::~Person() 
{
	cnt --;
	cout << "~Person is called" << endl;
}

Person::Person() 
{
	cout << "Person() called" << endl;
	cnt++;
}

// 初始化列表
Person::Person(int id, const char *name) : m_id(id)
{
	cnt++;
	cout << "Person(int id, const char *name) called" << endl;
	/*
	m_id = id;
	*/
	strncpy(this->m_name, name, NAMESIZE);
}

Person::Person(const Person &p)
{
	cnt++;
	cout << "Person(const Person &p) called" << endl;
	m_id = p.m_id;
	strncpy(m_name, p.m_name, NAMESIZE);
}

void Person::show()
{
	cout << this->m_id << ", " << this->m_name << endl;
}

void Person::setId(int id)
{
	this->m_id = id;
}
void Person::setName(const char *name)
{
	strncpy(this->m_name, name, NAMESIZE);
}

int Person::getCnt()
{
	return cnt;
}

// 显示Person对象的信息
void showPerson(const Person &s)
{
	cout << "id:" << s.m_id << endl;
	cout << "name:" << s.m_name << endl;
}

// const不能缺省
int Person::getId() const
{
	return m_id;
}

void test()
{
	// p1对象
	Person p1(100, "小黑"); // 带参数的构造方法
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
	Person p2; // 无参的构造方法
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
	Person p3 = p1; // 拷贝构造方法
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
	Person p4(p3); // 拷贝构造方法
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
	Person *p5 = new Person(2, "指针");
	cout << "现在有" << Person::getCnt() << "个对象" << endl;

	p1.show();

	cout << "getId:" << p1.getId() << endl;

	p3.show();
	p4.show();

	p2.setId(1);
	p2.setName("小白");

	p2.show();

	showPerson(*p5);

	delete p5;
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
}

int main(void)
{
	test();
	
	cout << "函数调用结束" << endl;
	cout << "现在有" << Person::getCnt() << "个对象" << endl;
	printf("bye-bye\n");

	return 0;
}

